package kayao.client.network.message;

import java.util.Vector;
import kayao.client.data.King;
import kayao.client.data.SharedMemory;
import kayao.client.data.Slave;
import kayao.client.scene.AreaManager;
import kayao.client.scene.Region;
import kayao.common.Client;
import kayao.common.KayaoValues;
import kayao.common.NetworkUtils;

public class KingRequestMessage extends Message{

	private static int mLastMessageId=0;
	private static final int RETRIES = 5;
	private static final int TIMEOUT_LENGTH_MILLIS = 3000;
	private static final int PRIORITY = PRIORITY_MEDIUM;

	public KingRequestMessage(String targetAddress) {
		super(targetAddress, RETRIES, TIMEOUT_LENGTH_MILLIS, PRIORITY);
		createPacketData();
		if(mMessageId>mLastMessageId)
			mLastMessageId=mMessageId;
	}

	@Override
	public String type() {
		// TODO Auto-generated method stub
		return "KingRequest";
	}
	public static int getLastMessageId()
	{
		return mLastMessageId;
	}
	@Override
	public void createPacketData() {
		// 4(magic nr) + 1(king req id)+message counter + 4(this client id) + 1(nr regions) + 1(regionId) * number of subscribed areas
		mSendData = new byte[14 + AreaManager.getSubscribedAreasCount()];
		int index = 0;

		// Insert magic number
		NetworkUtils.insertIntToByteArray(mSendData, index, KayaoValues.MAGIC_NUMBER);
		index += 4;
		// Insert message id
		mSendData[index] = KayaoValues.KING_REQUEST_MESSAGE;
		index++;
		//Insert the message counter
		NetworkUtils.insertIntToByteArray(mSendData, index, mMessageId);
		index+=4;
		// Insert local client id
		NetworkUtils.insertIntToByteArray(mSendData, index, SharedMemory.getInstance().getLocalId());
		index += 4;
		// Insert number of subscribed regions
		mSendData[index] = (byte)AreaManager.getSubscribedAreasCount();
		index++;
		// Insert the region of requesting entity
		int currentArea = AreaManager.getCurrentRegion();
		mSendData[index] = (byte)currentArea;
		index++;
		// Insert the rest of the subscribed areas
		Region[] subscribedRegions = AreaManager.getSubscribedRegions();
		for (int i = 0; i < subscribedRegions.length; i++) {
			if (i != currentArea) {
				if (subscribedRegions[i].isSubscribed()) {
					mSendData[index] = (byte)i;
					index++;
				}
			}
		}
	}

	public static boolean processPacket(byte[] receiveData, Message msg){

		String[] kings = new String[KayaoValues.NUMBER_OF_KINGDOMS];

		// Check which regions were asked for in previous request to which this is a response
		int index = 13;
		int i;
		Vector<Integer> regions = new Vector<Integer>();
		if (msg == null){
			System.out.println("[KingRequestMessage] - MSG IS NULL");
		}
		int regionsCount = NetworkUtils.unsignedByteToInt(msg.getData()[index]);
		index++;

		// Check which regions were requested
		for(i=0; i<regionsCount; i++){
			regions.add(NetworkUtils.unsignedByteToInt(msg.getData()[index+i]));
		}

		index = 9;		// Already processed: magic number (b), msg id (int32), msg counter (int32)
		int kingId;
		int kingdom;
		int teamId;
		String kingName ="";
		String kingIp;

		// Get number of kings
		int numberOfKings = NetworkUtils.unsignedByteToInt(receiveData[index]);
		index++;
		//		System.out.println("number of kings: " + numberOfKings);

		for (i = 0; i < numberOfKings; i++) {
			// Get king id
			kingId = NetworkUtils.insertByteArrayToInt(receiveData, index);
			index += 4;
			kingdom = regions.get(i);
			System.out.println("[KingRequestMessage] - King id: " + kingId + "For region: "+kingdom);
			if(kingId==0)	// If asking for a king in an empty region and I'm not in it
				continue;

			// Get team id
			teamId = NetworkUtils.unsignedByteToInt(receiveData[index]);	// TODO Remove team id from message
			index++;														// since it is never used

			int nameLength = NetworkUtils.unsignedByteToInt(receiveData[index]);
			index++;
			// Get client name
			for (int j = 0; j < nameLength; j++) {
				kingName += (char)receiveData[index];
				index ++;
			}

			final int first = NetworkUtils.unsignedByteToInt(receiveData[index]);
			final int second = NetworkUtils.unsignedByteToInt(receiveData[index + 1]);
			final int third = NetworkUtils.unsignedByteToInt(receiveData[index + 2]);
			final int fourth = NetworkUtils.unsignedByteToInt(receiveData[index + 3]);
			index += 4;
			kingIp = first + "." + second + "." + third + "." + fourth;

			//System.out.println(SharedMemory.getInstance().getMyself().getIP());
			if(kingIp.equals(SharedMemory.getInstance().getMyself().getIP())) {
				SharedMemory.getInstance().setKing(new King((byte)kingdom));
				//System.out.println("I'm my king!");
			}
			// Set IP to the position of that kingdom in list
			kings[kingdom]=kingIp;

			//System.out.println(kingIp);

			if(!SharedMemory.getInstance().hasClient(kingId)){
				System.out.println("[KingRequestMessage] - KingName: "+kingName+", KingID: "+kingId+", KingIP: "+kingIp+", KingTeam: "+teamId);
				SharedMemory.getInstance().addClient(new Client(kingName,kingId,kingIp,teamId));
			}
		}
		return Slave.updateMyKings(kings);
	}
}
